home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / dkong.c < prev    next >
C/C++ Source or Header  |  2000-04-19  |  11KB  |  377 lines

  1. /***************************************************************************
  2.  
  3.   vidhrdw.c
  4.  
  5.   Functions to emulate the video hardware of the machine.
  6.  
  7. ***************************************************************************/
  8.  
  9. #include "driver.h"
  10. #include "vidhrdw/generic.h"
  11.  
  12.  
  13. static int flipscreen;
  14. static int gfx_bank,palette_bank,grid_on;
  15. static const unsigned char *color_codes;
  16.  
  17.  
  18.  
  19. /***************************************************************************
  20.  
  21.   Convert the color PROMs into a more useable format.
  22.  
  23.   Donkey Kong has two 256x4 palette PROMs and one 256x4 PROM which contains
  24.   the color codes to use for characters on a per row/column basis (groups of
  25.   of 4 characters in the same column - actually row, since the display is
  26.   rotated)
  27.   The palette PROMs are connected to the RGB output this way:
  28.  
  29.   bit 3 -- 220 ohm resistor -- inverter  -- RED
  30.         -- 470 ohm resistor -- inverter  -- RED
  31.         -- 1  kohm resistor -- inverter  -- RED
  32.   bit 0 -- 220 ohm resistor -- inverter  -- GREEN
  33.   bit 3 -- 470 ohm resistor -- inverter  -- GREEN
  34.         -- 1  kohm resistor -- inverter  -- GREEN
  35.         -- 220 ohm resistor -- inverter  -- BLUE
  36.   bit 0 -- 470 ohm resistor -- inverter  -- BLUE
  37.  
  38. ***************************************************************************/
  39. void dkong_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
  40. {
  41.     int i;
  42.     #define TOTAL_COLORS(gfxn) (Machine->gfx[gfxn]->total_colors * Machine->gfx[gfxn]->color_granularity)
  43.     #define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs])
  44.  
  45.  
  46.     for (i = 0;i < 256;i++)
  47.     {
  48.         int bit0,bit1,bit2;
  49.  
  50.  
  51.         /* red component */
  52.         bit0 = (color_prom[256] >> 1) & 1;
  53.         bit1 = (color_prom[256] >> 2) & 1;
  54.         bit2 = (color_prom[256] >> 3) & 1;
  55.         *(palette++) = 255 - (0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2);
  56.         /* green component */
  57.         bit0 = (color_prom[0] >> 2) & 1;
  58.         bit1 = (color_prom[0] >> 3) & 1;
  59.         bit2 = (color_prom[256] >> 0) & 1;
  60.         *(palette++) = 255 - (0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2);
  61.         /* blue component */
  62.         bit0 = (color_prom[0] >> 0) & 1;
  63.         bit1 = (color_prom[0] >> 1) & 1;
  64.         *(palette++) = 255 - (0x55 * bit0 + 0xaa * bit1);
  65.  
  66.         color_prom++;
  67.     }
  68.  
  69.     color_prom += 256;
  70.     /* color_prom now points to the beginning of the character color codes */
  71.     color_codes = color_prom;    /* we'll need it later */
  72. }
  73.  
  74. /***************************************************************************
  75.  
  76.   Convert the color PROMs into a more useable format.
  77.  
  78.   Donkey Kong 3 has two 512x8 palette PROMs and one 256x4 PROM which contains
  79.   the color codes to use for characters on a per row/column basis (groups of
  80.   of 4 characters in the same column - actually row, since the display is
  81.   rotated)
  82.   Interstingly, bytes 0-255 of the palette PROMs contain an inverted palette,
  83.   as other Nintendo games like Donkey Kong, while bytes 256-511 contain a non
  84.   inverted palette. This was probably done to allow connection to both the
  85.   special Nintendo and a standard monitor.
  86.   I don't know the exact values of the resistors between the PROMs and the
  87.   RGB output, but they are probably the usual:
  88.  
  89.   bit 7 -- 220 ohm resistor -- inverter  -- RED
  90.         -- 470 ohm resistor -- inverter  -- RED
  91.         -- 1  kohm resistor -- inverter  -- RED
  92.         -- 2.2kohm resistor -- inverter  -- RED
  93.         -- 220 ohm resistor -- inverter  -- GREEN
  94.         -- 470 ohm resistor -- inverter  -- GREEN
  95.         -- 1  kohm resistor -- inverter  -- GREEN
  96.   bit 0 -- 2.2kohm resistor -- inverter  -- GREEN
  97.  
  98.   bit 3 -- 220 ohm resistor -- inverter  -- BLUE
  99.         -- 470 ohm resistor -- inverter  -- BLUE
  100.         -- 1  kohm resistor -- inverter  -- BLUE
  101.   bit 0 -- 2.2kohm resistor -- inverter  -- BLUE
  102.  
  103. ***************************************************************************/
  104. void dkong3_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
  105. {
  106.     int i;
  107.     #define TOTAL_COLORS(gfxn) (Machine->gfx[gfxn]->total_colors * Machine->gfx[gfxn]->color_granularity)
  108.     #define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs])
  109.  
  110.  
  111.     for (i = 0;i < 256;i++)
  112.     {
  113.         int bit0,bit1,bit2,bit3;
  114.  
  115.  
  116.         /* red component */
  117.         bit0 = (color_prom[0] >> 4) & 0x01;
  118.         bit1 = (color_prom[0] >> 5) & 0x01;
  119.         bit2 = (color_prom[0] >> 6) & 0x01;
  120.         bit3 = (color_prom[0] >> 7) & 0x01;
  121.         *(palette++) = 255 - (0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3);
  122.         /* green component */
  123.         bit0 = (color_prom[0] >> 0) & 0x01;
  124.         bit1 = (color_prom[0] >> 1) & 0x01;
  125.         bit2 = (color_prom[0] >> 2) & 0x01;
  126.         bit3 = (color_prom[0] >> 3) & 0x01;
  127.         *(palette++) = 255 - (0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3);
  128.         /* blue component */
  129.         bit0 = (color_prom[256] >> 0) & 0x01;
  130.         bit1 = (color_prom[256] >> 1) & 0x01;
  131.         bit2 = (color_prom[256] >> 2) & 0x01;
  132.         bit3 = (color_prom[256] >> 3) & 0x01;
  133.         *(palette++) = 255 - (0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3);
  134.  
  135.         color_prom++;
  136.     }
  137.  
  138.     color_prom += 256;
  139.     /* color_prom now points to the beginning of the character color codes */
  140.     color_codes = color_prom;    /* we'll need it later */
  141. }
  142.  
  143.  
  144.  
  145. int dkong_vh_start(void)
  146. {
  147.     gfx_bank = 0;
  148.     palette_bank = 0;
  149.  
  150.     return generic_vh_start();
  151. }
  152.  
  153.  
  154.  
  155. WRITE_HANDLER( dkongjr_gfxbank_w )
  156. {
  157.     if (gfx_bank != (data & 1))
  158.     {
  159.         gfx_bank = data & 1;
  160.         memset(dirtybuffer,1,videoram_size);
  161.     }
  162. }
  163.  
  164. WRITE_HANDLER( dkong3_gfxbank_w )
  165. {
  166.     if (gfx_bank != (~data & 1))
  167.     {
  168.         gfx_bank = ~data & 1;
  169.         memset(dirtybuffer,1,videoram_size);
  170.     }
  171. }
  172.  
  173.  
  174.  
  175. WRITE_HANDLER( dkong_palettebank_w )
  176. {
  177.     int newbank;
  178.  
  179.  
  180.     newbank = palette_bank;
  181.     if (data & 1)
  182.         newbank |= 1 << offset;
  183.     else
  184.         newbank &= ~(1 << offset);
  185.  
  186.     if (palette_bank != newbank)
  187.     {
  188.         palette_bank = newbank;
  189.         memset(dirtybuffer,1,videoram_size);
  190.     }
  191. }
  192.  
  193. WRITE_HANDLER( radarscp_grid_enable_w )
  194. {
  195.     grid_on = data & 1;
  196. }
  197.  
  198. WRITE_HANDLER( radarscp_grid_color_w )
  199. {
  200.     int r,g,b;
  201.  
  202.     r = ((~data >> 0) & 0x01) * 0xff;
  203.     g = ((~data >> 1) & 0x01) * 0xff;
  204.     b = ((~data >> 2) & 0x01) * 0xff;
  205. //    palette_change_color(257,r,g,b);
  206.     palette_change_color(257,0x00,0x00,0xff);
  207. }
  208.  
  209. WRITE_HANDLER( dkong_flipscreen_w )
  210. {
  211.     if (flipscreen != (~data & 1))
  212.     {
  213.         flipscreen = ~data & 1;
  214.         memset(dirtybuffer,1,videoram_size);
  215.     }
  216. }
  217.  
  218. /***************************************************************************
  219.  
  220.   Draw the game screen in the given osd_bitmap.
  221.   Do NOT call osd_update_display() from this function, it will be called by
  222.   the main emulation engine.
  223.  
  224. ***************************************************************************/
  225.  
  226. static void draw_tiles(struct osd_bitmap *bitmap)
  227. {
  228.     int offs;
  229.  
  230.     /* for every character in the Video RAM, check if it has been modified */
  231.     /* since last time and update it accordingly. */
  232.     for (offs = videoram_size - 1;offs >= 0;offs--)
  233.     {
  234.         if (dirtybuffer[offs])
  235.         {
  236.             int sx,sy;
  237.             int charcode,color;
  238.  
  239.  
  240.             dirtybuffer[offs] = 0;
  241.  
  242.             sx = offs % 32;
  243.             sy = offs / 32;
  244.  
  245.             charcode = videoram[offs] + 256 * gfx_bank;
  246.             /* retrieve the character color from the PROM */
  247.             color = (color_codes[offs % 32 + 32 * (offs / 32 / 4)] & 0x0f) + 0x10 * palette_bank;
  248.  
  249.             if (flipscreen)
  250.             {
  251.                 sx = 31 - sx;
  252.                 sy = 31 - sy;
  253.             }
  254.  
  255.             drawgfx(tmpbitmap,Machine->gfx[0],
  256.                     charcode,color,
  257.                     flipscreen,flipscreen,
  258.                     8*sx,8*sy,
  259.                     &Machine->drv->visible_area,TRANSPARENCY_NONE,0);
  260.         }
  261.     }
  262.  
  263.  
  264.     /* copy the character mapped graphics */
  265.     copybitmap(bitmap,tmpbitmap,0,0,0,0,&Machine->drv->visible_area,TRANSPARENCY_NONE,0);
  266. }
  267.  
  268. static void draw_sprites(struct osd_bitmap *bitmap)
  269. {
  270.     int offs;
  271.  
  272.     /* Draw the sprites. */
  273.     for (offs = 0;offs < spriteram_size;offs += 4)
  274.     {
  275.         if (spriteram[offs])
  276.         {
  277.             /* spriteram[offs + 2] & 0x40 is used by Donkey Kong 3 only */
  278.             /* spriteram[offs + 2] & 0x30 don't seem to be used (they are */
  279.             /* probably not part of the color code, since Mario Bros, which */
  280.             /* has similar hardware, uses a memory mapped port to change */
  281.             /* palette bank, so it's limited to 16 color codes) */
  282.  
  283.             int x,y;
  284.  
  285.             x = spriteram[offs + 3] - 8;
  286.             y = 240 - spriteram[offs] + 7;
  287.  
  288.             if (flipscreen)
  289.             {
  290.                 x = 240 - x;
  291.                 y = 240 - y;
  292.  
  293.                 drawgfx(bitmap,Machine->gfx[1],
  294.                         (spriteram[offs + 1] & 0x7f) + 2 * (spriteram[offs + 2] & 0x40),
  295.                         (spriteram[offs + 2] & 0x0f) + 16 * palette_bank,
  296.                         !(spriteram[offs + 2] & 0x80),!(spriteram[offs + 1] & 0x80),
  297.                         x,y,
  298.                         &Machine->drv->visible_area,TRANSPARENCY_PEN,0);
  299.  
  300.                 /* draw with wrap around - this fixes the 'beheading' bug */
  301.                 drawgfx(bitmap,Machine->gfx[1],
  302.                         (spriteram[offs + 1] & 0x7f) + 2 * (spriteram[offs + 2] & 0x40),
  303.                         (spriteram[offs + 2] & 0x0f) + 16 * palette_bank,
  304.                         (spriteram[offs + 2] & 0x80),(spriteram[offs + 1] & 0x80),
  305.                         x-256,y,
  306.                         &Machine->drv->visible_area,TRANSPARENCY_PEN,0);
  307.             }
  308.             else
  309.             {
  310.                 drawgfx(bitmap,Machine->gfx[1],
  311.                         (spriteram[offs + 1] & 0x7f) + 2 * (spriteram[offs + 2] & 0x40),
  312.                         (spriteram[offs + 2] & 0x0f) + 16 * palette_bank,
  313.                         (spriteram[offs + 2] & 0x80),(spriteram[offs + 1] & 0x80),
  314.                         x,y,
  315.                         &Machine->drv->visible_area,TRANSPARENCY_PEN,0);
  316.  
  317.                 /* draw with wrap around - this fixes the 'beheading' bug */
  318.                 drawgfx(bitmap,Machine->gfx[1],
  319.                         (spriteram[offs + 1] & 0x7f) + 2 * (spriteram[offs + 2] & 0x40),
  320.                         (spriteram[offs + 2] & 0x0f) + 16 * palette_bank,
  321.                         (spriteram[offs + 2] & 0x80),(spriteram[offs + 1] & 0x80),
  322.                         x+256,y,
  323.                         &Machine->drv->visible_area,TRANSPARENCY_PEN,0);
  324.             }
  325.         }
  326.     }
  327. }
  328.  
  329. static void draw_grid(struct osd_bitmap *bitmap)
  330. {
  331.     const unsigned char *table = memory_region(REGION_GFX3);
  332.     int x,y,counter;
  333.  
  334.     counter = flipscreen ? 0x000 : 0x400;
  335.  
  336.     x = Machine->drv->visible_area.min_x;
  337.     y = Machine->drv->visible_area.min_y;
  338.     while (y <= Machine->drv->visible_area.max_y)
  339.     {
  340.         x = 4 * (table[counter] & 0x7f);
  341.         if (x >= Machine->drv->visible_area.min_x &&
  342.                 x <= Machine->drv->visible_area.max_x)
  343.         {
  344.             if (table[counter] & 0x80)    /* star */
  345.             {
  346.                 if (rand() & 1)    /* noise coming from sound board */
  347.                     plot_pixel(bitmap,x,y,Machine->pens[256]);
  348.             }
  349.             else if (grid_on)            /* radar */
  350.                 plot_pixel(bitmap,x,y,Machine->pens[257]);
  351.         }
  352.  
  353.         counter++;
  354.  
  355.         if (x >= 4 * (table[counter] & 0x7f))
  356.             y++;
  357.     }
  358. }
  359.  
  360. void radarscp_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  361. {
  362.     palette_change_color(256,0xff,0x00,0x00);    /* stars */
  363.  
  364.     if (palette_recalc())
  365.         memset(dirtybuffer,1,videoram_size);
  366.  
  367.     draw_tiles(bitmap);
  368.     draw_grid(bitmap);
  369.     draw_sprites(bitmap);
  370. }
  371.  
  372. void dkong_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  373. {
  374.     draw_tiles(bitmap);
  375.     draw_sprites(bitmap);
  376. }
  377.